Skip to content

feat: post-episode Up Next prompt + honor autoPlayNext setting (#86) - #126

Merged
ProdigyV21 merged 1 commit into
mainfrom
feat/post-episode-prompt
Apr 5, 2026
Merged

feat: post-episode Up Next prompt + honor autoPlayNext setting (#86)#126
ProdigyV21 merged 1 commit into
mainfrom
feat/post-episode-prompt

Conversation

@ProdigyV21

Copy link
Copy Markdown
Owner

Summary

Closes #86.

Adds the post-episode "Up Next" prompt with Continue / Cancel buttons and a 10-second countdown at the end of every TV episode. Also fixes a long-standing bug where the player ignored the autoPlayNext profile setting entirely.

Root cause

Two separate bugs, both in PlayerScreen.kt:1251-1262:

  1. When a TV episode ended, onPlayNext() was called immediately with zero UI feedback. Users were abruptly dropped into the next episode with no way to cancel except by hitting back.
  2. The handler didn't check the profile's autoPlayNext setting at all — users who disabled auto-advance in Settings still got silently advanced at the end of every episode.

NextEpisodeOverlay.kt has been fully implemented for a while (~260 LOC, countdown, focus handling, Back/Escape cancel, Enter confirm) but was never invoked anywhere — confirmed by grep across the entire project. This PR finally wires it up.

Changes

1. Player respects the autoPlayNext setting

  • New autoPlayNext: Boolean = true field on PlayerUiState.
  • PlayerViewModel.loadDetails() loads it from DataStore via profileManager.profileBooleanKey("auto_play_next") — the same key SettingsViewModel already uses to persist the toggle. This was the missing link that made the setting a no-op for the player.

2. Overlay state machine in PlayerScreen

  • Added showNextEpisodePrompt + pendingNextSeason / pendingNextEpisode / pendingNextAddonId / pendingNextSourceName / pendingNextBingeGroup state vars.
  • Replaced the unconditional onPlayNext(...) call in the STATE_ENDED branch with a state transition that captures the next-episode parameters and shows the overlay.
  • Guards:
    • Only fires when mediaType == TV (unchanged).
    • Gated on uiState.autoPlayNext — when disabled we stay on the ended frame.
    • Re-entry guard !showNextEpisodePrompt prevents the tick loop (200-500ms) from re-triggering.
    • Doesn't fire while showSourceMenu, showSubtitleMenu, or uiState.error != null.
  • Added showNextEpisodePrompt to the container-focus LaunchedEffect key set so the overlay's own onKeyEvent handler receives D-pad input without the background container stealing focus.

3. Render the overlay

Placed after StreamSelector in the UI tree. Uses:

  • showTitleuiState.title (show name)
  • episodeTitle → generic "Episode N" for the upcoming episode (see note below)
  • seasonNumber / episodeNumberpendingNextSeason / pendingNextEpisode
  • episodeImageuiState.backdropUrl (show backdrop — we don't have the next episode's still)
  • countdownSeconds → 10
  • onPlayNext → hide overlay + call the existing onPlayNext(...) lambda with the pending parameters
  • onCancel → hide overlay, stay on the ended frame

Why a generic "Episode N" label instead of the next episode's title

Fetching the upcoming episode's metadata (name, overview, still image) would require an extra TMDB /tv/{id}/season/{n}/episode/{m} round-trip at end-of-episode time. For this PR I'm keeping the scope tight and using a generic label — the show title, S/E number, and show backdrop still give users enough context to decide Continue / Cancel. A follow-up PR could prefetch the next episode's still during playback if we want the richer preview.

Test plan

  1. Enable auto-play next in Settings (it's the default, true).
  2. Play an episode near the end and let it finish.
  3. Verify the "Up Next" overlay slides in from the right with a 10-second countdown.
  4. Verify Left/Right moves focus between Play Now and Cancel.
  5. Verify Enter on Play Now advances immediately.
  6. Verify Enter on Cancel hides the overlay and stays on the frame.
  7. Verify Back/Escape cancels.
  8. Verify the countdown auto-advances at 0.
  9. Disable auto-play next in Settings.
  10. Play an episode to the end.
  11. Verify the player stays on the ended frame with no advance and no overlay.

Risk

Low. The existing STATE_ENDED path was unconditional and ignored the setting — this PR strictly adds behavior (setting gate + overlay UI) and replaces the auto-advance with an overlay-gated advance. When autoPlayNext is true and the user takes no action, the net behavior is the same as before plus a 10-second countdown UI. When autoPlayNext is false, the new behavior (stay on frame) is what users who disabled the setting were expecting all along.

When a TV episode ends, PlayerScreen previously called onPlayNext()
immediately with zero UI feedback — users were abruptly dropped into the
next episode with no way to cancel except by hitting back. It also ignored
the profile's autoPlayNext setting entirely, so users who disabled
auto-advance still got silently advanced at the end of every episode.

NextEpisodeOverlay has been fully implemented for a while (~260 LOC with
countdown ring, focus handling, Back/Escape cancel, Enter confirm) but was
never invoked anywhere — confirmed by grep. This PR finally wires it up.

Changes:
- Add `autoPlayNext: Boolean` to PlayerUiState, load it from DataStore at
  the start of loadDetails via the existing
  profileManager.profileBooleanKey("auto_play_next") path that
  SettingsViewModel already uses to persist the toggle. The player now
  respects the setting for the first time.
- Add overlay state vars (showNextEpisodePrompt + pending next-episode
  metadata) to PlayerScreen.
- Replace the unconditional onPlayNext() call in the STATE_ENDED handler
  with a state transition that shows the overlay. Gated on autoPlayNext —
  when disabled we stay on the ended frame instead of advancing.
- Add re-entry guards: only fires once per session (showNextEpisodePrompt
  guard), doesn't fire while error/source/subtitle overlays are visible.
- Render NextEpisodeOverlay after StreamSelector in the UI tree, wired to
  onPlayNext (advances) / onCancel (stays on ended frame) / 10-second
  countdown (auto-advances).
- Include showNextEpisodePrompt in the container-focus LaunchedEffect key
  set so the overlay's own onKeyEvent handler receives D-pad input
  without the background container stealing focus.
- Use a generic "Episode N" label in the overlay rather than exposing the
  current episode's title, since fetching the *upcoming* episode's
  metadata would require an extra TMDB round-trip during playback. Show
  title, S/E number, and backdrop give users enough context to decide.

Closes #86
@ProdigyV21
ProdigyV21 merged commit 1c4d2b0 into main Apr 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Post-episode playback prompt

1 participant